package com.android.vestel.photoroid;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class PhotoroidService extends Service {
	private final String TAG = "Photoroid Background Service";
	public final static String PROG_STAT_DISABLED = "0";
	public final static String PROG_STAT_PICASA_DISABLED = "1";
	public final static String PROG_STAT_FLICKR_DISABLED = "2";
	public final static String PROG_STAT_EXTERNAL_DISABLED = "3";
	public final static String PROG_STAT_PICASA_ENABLED = "4";
	public final static String PROG_STAT_FLICKR_ENABLED = "5";
	public final static String PROG_STAT_EXTERNAL_ENABLED = "6";
	public final static String PROG_STAT_SDCARD_NOT_EXIST = "7";
	private String ProgramState;

	private DataHelper dataHelper;
	StringBuilder sb;
	StringBuilder sb2;
	ArrayList<String> ImageURIs;
	IntentFilter filter;
	BroadcastReceiver mSDInfoReceiver;
	Handler han;
	Timer timer;
	TimerTask sync;
	SyncPhotos syncHelper;
	Context context = getBaseContext();
	boolean scheduleFlag = false;
	String SyncRefreshRate = "300000";
	String sdCardDir = "/sdcard/";

	@Override
	public void onCreate() {

		Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
		Log.d(TAG, "onCreate");

		updateProgramState();
		ImageURIs = new ArrayList<String>();

		// sdcard listener
		mSDInfoReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context arg0, Intent arg1) {
				// TODO change program state
				Log.e("PhotoroidService", "SD Card Removed");
				updateProgramState(PROG_STAT_SDCARD_NOT_EXIST, "null");
			}
		};
		filter = new IntentFilter(Intent.ACTION_MEDIA_REMOVED);
		filter.addDataScheme("file");
		registerReceiver(mSDInfoReceiver, new IntentFilter(filter));

		syncHelper = new SyncPhotos(getBaseContext());

		han = new Handler();
		sync = new TimerTask() {

			@Override
			public void run() {
				han.post(new Runnable() {

					@Override
					public void run() {
						if (!syncHelper.synchronize()) {
							Log.e(TAG,
									"Synchronization failed. Stopping Service.");
							stopSelf();
						} else {
							Log.e(TAG, "Synchronization waiting...");
						}
					}
				});
			}

		};
		timer = new Timer();
	}

	@Override
	public void onStart(Intent intent, int startid) {
		Log.e(TAG, "onStart");
		Log.e(TAG, "ProgramState = " + ProgramState);
		
		if(!scheduleFlag){
			Thread th = new Thread(new Runnable() {
				@Override
				public void run() {
					timer.schedule(sync, 1000, Integer.valueOf(SyncRefreshRate));
				}
			});
			th.start();
			scheduleFlag = true;
		}
		Log.e(TAG, "Synchronization timer is scheduled.");
		//three_two_one_action();
		//Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
	}

	private void three_two_one_action() {
		if (ProgramState.equals(PROG_STAT_DISABLED)) {
			Log.e(TAG, "ProgramState = disabled. Stopping the service...");
			// kill the service
			stopSelf();
		} else if (ProgramState.equals(PROG_STAT_PICASA_DISABLED)) {
			Log.e(TAG,
					"ProgramState = picasa disabled. Stopping the service...");
			stopSelf();
		} else if (ProgramState.equals(PROG_STAT_FLICKR_DISABLED)) {
			Log.e(TAG,
					"ProgramState = flickr disabled. Stopping the service...");
			stopSelf();
		} else if (ProgramState.equals(PROG_STAT_EXTERNAL_DISABLED)) {
			Log.e(TAG,
					"ProgramState = external disabled. Stopping the service...");
			stopSelf();
		} else if (ProgramState.equals(PROG_STAT_PICASA_ENABLED)) {
			Log.e(TAG, "ProgramState = picasa enabled. Stopping the service...");
			// stopSelf();
			if (PhotoroidActivity.isSDCardMounted()) {
				Log.e(TAG, "SD Card is mounted");
				getImageURIs();
				if (!(ImageURIs.size() <= 0)) {
					Bundle b = new Bundle();
					b.putStringArrayList("ImageURIs", ImageURIs);
					showImages(b);
					b.clear();
				}
			}
		} else if (ProgramState.equals(PROG_STAT_FLICKR_ENABLED)) {
			Log.e(TAG, "ProgramState = flickr enabled");
			//stopSelf();
			if (PhotoroidActivity.isSDCardMounted()) {
				Log.e(TAG, "SD Card is mounted");
				getImageURIs();
				if (!(ImageURIs.size() <= 0)) {
					Bundle b = new Bundle();
					b.putStringArrayList("ImageURIs", ImageURIs);
					showImages(b);
					b.clear();
				}
			}
		} else if (ProgramState.equals(PROG_STAT_EXTERNAL_ENABLED)) {
			Log.e(TAG, "ProgramState = external enabled");
			// stopSelf();
			if (PhotoroidActivity.isSDCardMounted()) {
				Log.e(TAG, "SD Card is mounted");
				getImageURIs(Environment.getExternalStorageDirectory());
				if (!(ImageURIs.size() <= 0)) {
					Bundle b = new Bundle();
					b.putStringArrayList("ImageURIs", ImageURIs);
					showImages(b);
					b.clear();
				}
			} else
				Log.e(TAG, "SD Card isn't mounted");
		} else if (ProgramState.equals(PROG_STAT_SDCARD_NOT_EXIST)) {
			// TODO: alert no sd card
			Log.e(TAG, "ProgramState = SD card does not exist");
			stopSelf();
		} else {
			Log.e(TAG, "The program state is not defined.");
			// updateProgramState(PROG_STAT_DISABLED,"null");
			stopSelf();
		}
	}

	private void getImageURIs(File f) {
		if (f == null) {
			Log.e(TAG, "null file pointer is given to getImageURIsR.");
		}
		Queue<File> dirQueue = new LinkedList<File>();
		File[] farr = null;
		if (f.isDirectory() == true)
			dirQueue.add(f);
		Log.d("getImageURIsR", "queue");
		while (!dirQueue.isEmpty()) {
			f = dirQueue.remove();
			Log.d("getImageURIsR", "while");
			Log.d("getImageURIsR", f.getName().toString());

			farr = f.listFiles(new FilenameFilter() {

				public boolean accept(File dir, String name) {
					return !((name.startsWith("."))
							|| (name.contains("LOST.DIR")) || name
							.contains("DCIM"));
				}
			});

			for (int i = 0; i < farr.length; i++) {
				Log.d("getImageURIsR", "for");
				Log.d("getImageURIsR", farr[i].getName().toString());

				if (farr[i].isDirectory() == true) {
					dirQueue.add(farr[i]);
				} else {

					if (farr[i].getName().endsWith(".jpg")
							|| farr[i].getName().endsWith(".png"))
						ImageURIs.add(farr[i].getAbsolutePath());

				}
			}
		}
		Log.d("getImageURIs", "cikti");
	}

	private void getImageURIs() {
		File[] farr;
		File f = new File(SyncPhotos.downloadDir);
		Log.e(TAG, "Getting images from SD Card");
		if (f.isDirectory() == true) {
			farr = f.listFiles(new FilenameFilter() {
				public boolean accept(File dir, String name) {
					return !((name.startsWith("."))
							|| (name.contains("LOST.DIR")) || name
							.contains("DCIM"));
				}
			});
			for (int i = 0; i < farr.length; i++) {
				if (farr[i].isFile()) {
					if (farr[i].getName().endsWith(".jpg")
							|| farr[i].getName().endsWith(".png")) {
						ImageURIs.add(farr[i].getAbsolutePath());
					}
				}

			}
		}
		Log.d("getImageURIs", "cikti");
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.e(TAG, "startService is called");
		if(intent != null){
			if(intent.hasExtra("ForceShowSlide")){// open slide show
				Log.e(TAG, "Forcing to start slideshow...");
				three_two_one_action();
			}
		}
		return super.onStartCommand(intent, flags, startId);
	}

	private void showImages(Bundle b) {
		Intent showImagesIntent = new Intent(getBaseContext(),
				ShowImageActivity.class);
		showImagesIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		showImagesIntent.putExtras(b);
		getApplication().startActivity(showImagesIntent);
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onDestroy() {
		timer.cancel();
		unregisterReceiver(mSDInfoReceiver);
		Toast.makeText(this, "Service Stopped", Toast.LENGTH_SHORT).show();
		Log.d(TAG, "onDestroy");
		closeDBConnection();
	}

	private void openDBConnection() {
		if (dataHelper == null) {
			dataHelper = new DataHelper(this);
		}
		Log.e("PicasaFormActivity", "Database Connection Opened");
	}

	private void closeDBConnection() {
		if (dataHelper != null) {
			dataHelper.closeDB();
			dataHelper = null;
		}
		Log.e("PicasaFormActivity", "Database Connection Closed");

	}

	private String updateProgramState() {
		openDBConnection();
		ProgramState = dataHelper.selectAllOfSetting().get(
				DataHelper.PROGRAM_STATE);
		closeDBConnection();
		return ProgramState;
	}

	private void updateProgramState(String newProgramState,
			String newServiceProvider) {
		ProgramState = newProgramState;
		openDBConnection();
		dataHelper.updateSettingTable(newProgramState, newServiceProvider);
		closeDBConnection();
	}

}
